module tb();

   // multiply #(8) unit (
   // 					   .i_a(8'hab),
   // 					   .i_b(8'h56),
   // 					   .i_sign(1'b0)
   // 					   );

   multiply #(16) unit (
   						.i_a(16'habcd),
   						.i_b(16'h5678),
   						.i_sign(1'b1)
   						);
   
					   
endmodule // tb



module multiply(i_a, i_b, i_sign);
   parameter width = 8;
   parameter pps_num = width/2+1;

   input logic [width-1:0] i_a;
   input logic [width-1:0] i_b;
   input logic 			   i_sign;
   
   
   wire [width:0] 		   a = { i_sign & i_a[width-1], i_a };
   wire [width+1:0] 		   b = { {2{i_sign & i_b[width-1]}}, i_b };
   wire [width+2:0] 		   b_ext = { b, 1'b0 };
   
   
   logic signed [2:0] 		   booth2_array[pps_num-1:0]; // 0, +-1, +-2
   
   logic [width:0] 		   pp[pps_num-1:0];
   logic 			   S[pps_num-1:0]; // the last one is not needed
   logic 			   E[pps_num-1:0]; // the last one is not needed
   
   
   initial
     #10
	   
       begin
	  for(int i=0;i<=width;i+=2)	// total pps_num
	    begin
	       booth2_array[i/2] = b_ext[i] + b_ext[i+1] - 2*b_ext[i+2]; // 0,+-1,+-2
	       $display("booth2_array[%d] = %d", i/2, booth2_array[i/2]);
	    end
	  
	  // gen PPs and S, E
	  for(int i=0;i<pps_num;i++)
	    begin
	       case(booth2_array[i])
		 3'd0:
		   pp[i] = '0;
		 3'd1:
		   pp[i] = a;
		 3'd2:
		   pp[i] = a<<1;
		 -3'd1:
			   pp[i] = ~a;
		 -3'd2:
			   pp[i] = ~(a<<1);
	       endcase // case (booth2_array[i])
	       
	       //S (the same as the sign of booth2_array[i])
	       if(booth2_array[i] < 0)
		 S[i] = 1'b1;
	       else
		 S[i] = 1'b0;
	       //E, if booth2 recoding is 0 or has the same sign 
	       // with mutliplicand, E[i] is 1, otherwise 0
	       E[i] = (booth2_array[i] == 3'd0) ? 1'b1 : S[i] ~^ a[width]; 
	    end // for (int i=0;i<pps_num;i++)

	  for(int i=0;i<pps_num;i++)
	    $display("PP[%d] = 0x%x(%d)", i, pp[i], pp[i]);

	  for(int i=0;i<pps_num-1;i++)
	    $display("S[%d] = %d, E[%d] = %d", i, S[i], i, E[i]);
	  
       end // initial begin
endmodule // multiply

